package com.gp.study.mybatis.handler;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;

public class ResultSetHandler {

	public <T> T handResultSetPojo(ResultSet rs, Class<?> type) throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
		//单条处理，所以不用while
		if(rs.next()){
			String className = type.getName();
			Class<?> claz = Class.forName(className);
			Object pojo = claz.newInstance();
			if(null == pojo){
				throw new ClassNotFoundException(type.getName());
			}
			Field[] declaredFields = pojo.getClass().getDeclaredFields();
			// rs的结果，可能是几个字段，不全匹配 fields 所以不能根据索引
			for(Field field:declaredFields){
				setValue(rs,field,pojo);
			}
			return (T) pojo;
		}
		
		return null;
	}

	/**
	 * 根据 filed的类型，匹配赋值
	 * @param rs
	 * @param field
	 * @param pojo
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 * @throws SQLException 
	 */
	private void setValue(ResultSet rs, Field field, Object pojo) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, SQLException {
		Class<?> type = field.getType();
		Method setMethod = getSetMethod(pojo,field);
		Object value = getResult(rs,field);
		setMethod.invoke(pojo, value);
		
	}

	/**
     * 根据反射判断类型，从ResultSet中取对应类型参数
     */
    private Object getResult(ResultSet rs, Field field) throws SQLException {
        Class type = field.getType();
//        String dataName = HumpToUnderline(field.getName()); // 驼峰转下划线
        String dataName = field.getName();
        if (Integer.class == type || int.class == type ) {
            return rs.getInt(dataName);
        }else if (String.class == type) {
            return rs.getString(dataName);
        }else if(Long.class == type || long.class == type){
            return rs.getLong(dataName);
        }else if(Boolean.class == type || boolean.class == type){
            return rs.getBoolean(dataName);
        }else if(Double.class == type || double.class == type){
            return rs.getDouble(dataName);
        }
		throw new SQLException("no support typehandle found");
    }


	private Method getSetMethod(Object pojo, Field field) throws NoSuchMethodException, SecurityException {
		return pojo.getClass().getMethod("set"+firstWordCapital(field.getName()),field.getType());
	}
	
	 // 数据库下划线转Java驼峰命名
    public static String HumpToUnderline(String para){
        StringBuilder sb=new StringBuilder(para);
        int temp=0;
        if (!para.contains("_")) {
            for(int i=0;i<para.length();i++){
                if(Character.isUpperCase(para.charAt(i))){
                    sb.insert(i+temp, "_");
                    temp+=1;
                }
            }
        }
        return sb.toString().toUpperCase();
    }

    /**
     * 单词首字母大写
     */
    private String firstWordCapital(String word){
        String first = word.substring(0, 1);
        String tail = word.substring(1);
        return first.toUpperCase() + tail;
    }

}
